package com.love.marriage.oss.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.love.marriage.common.enums.ResultEnum;
import com.love.marriage.common.exceptions.FileException;
import com.love.marriage.config.MinioProperties;
import com.love.marriage.oss.entity.FileInfo;
import com.love.marriage.oss.mapper.FileInfoMapper;
import com.love.marriage.oss.service.FileInfoService;
import com.love.marriage.oss.service.MinioFileService;
import com.love.marriage.oss.vo.FileInfoVo;
import com.love.marriage.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * <p>
 * description: 文件信息表服务实现类
 * author: alex
 * createDate: 2023-01-30 14:08:29
 * version: 1.0.0
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class FileInfoServiceImp extends ServiceImpl<FileInfoMapper, FileInfo> implements FileInfoService {

    private final FileInfoMapper fileInfoMapper;

    private final MinioFileService minioFileService;

    private final MinioProperties minioProperties;

    @Override
    public Page<FileInfoVo> getPage(Long pageNum, Long pageSize, FileInfoVo fileInfoVo) {
        Page<FileInfoVo> page = new Page<>(pageNum == null ? 1 : pageNum, pageSize == null ? 10 : pageSize);
        return fileInfoMapper.getPage(page, fileInfoVo);
    }

    @Override
    public FileInfoVo queryFileInfo(Long id) throws Exception {
        FileInfoVo fileInfoVo = fileInfoMapper.queryFileInfo(id);
        if (fileInfoVo == null) {
            return null;
        }
        
        // 设置原文件预览URL
        String url = minioFileService.preview(fileInfoVo.getBucketName(), fileInfoVo.getUrl());
        if (StringUtils.isNotBlank(url) && url.startsWith(minioProperties.getOldUrl())) {
            url = minioProperties.getNewUrl() + url.substring(minioProperties.getOldUrl().length());
        }
        fileInfoVo.setPreUrl(url);
        
        // 设置缩略图预览URL（如果存在）
        if (StringUtils.isNotBlank(fileInfoVo.getThumbnailUrl())) {
            try {
                String thumbnailPreUrl = minioFileService.preview(fileInfoVo.getBucketName(), fileInfoVo.getThumbnailUrl());
                if (StringUtils.isNotBlank(thumbnailPreUrl) && thumbnailPreUrl.startsWith(minioProperties.getOldUrl())) {
                    thumbnailPreUrl = minioProperties.getNewUrl() + thumbnailPreUrl.substring(minioProperties.getOldUrl().length());
                }
                fileInfoVo.setThumbnailPreUrl(thumbnailPreUrl);
            } catch (Exception e) {
                log.error("生成缩略图预览URL失败: {}", e.getMessage(), e);
            }
        }
        
        return fileInfoVo;
    }

    @Override
    public FileInfoVo addFileInfo(String type, MultipartFile file) throws Exception {
        if (file == null) {
            throw new FileException(ResultEnum.IMAGE_NO_FOUNT);
        }
        FileInfoVo uploadFile = minioFileService.uploadFileWithThumbnail(file, type);
        FileInfo fileInfo = new FileInfo();
        BeanUtils.copyProperties(uploadFile, fileInfo);
        fileInfoMapper.insert(fileInfo);
        BeanUtils.copyProperties(fileInfo, uploadFile);
        
        // 设置原文件预览URL
        String url = minioFileService.preview(uploadFile.getBucketName(), uploadFile.getUrl());
        if (StringUtils.isNotBlank(url) && url.startsWith(minioProperties.getOldUrl())) {
            url = minioProperties.getNewUrl() + url.substring(minioProperties.getOldUrl().length());
        }
        uploadFile.setPreUrl(url);
        
        // 设置缩略图预览URL（如果存在）
        if (StringUtils.isNotBlank(uploadFile.getThumbnailUrl())) {
            try {
                String thumbnailPreUrl = minioFileService.preview(uploadFile.getBucketName(), uploadFile.getThumbnailUrl());
                if (StringUtils.isNotBlank(thumbnailPreUrl) && thumbnailPreUrl.startsWith(minioProperties.getOldUrl())) {
                    thumbnailPreUrl = minioProperties.getNewUrl() + thumbnailPreUrl.substring(minioProperties.getOldUrl().length());
                }
                uploadFile.setThumbnailPreUrl(thumbnailPreUrl);
            } catch (Exception e) {
                log.error("生成缩略图预览URL失败: {}", e.getMessage(), e);
            }
        }
        
        return uploadFile;
    }

    @Override
    public FileInfoVo updateFileInfo(Long id, String type, MultipartFile file) throws Exception {
        FileInfo fileInfo = this.getById(id);
        FileInfoVo uploadFile = null;
        if (file != null) {
            uploadFile = minioFileService.uploadFileWithThumbnail(file, type);
            BeanUtils.copyProperties(uploadFile, fileInfo, "id");
        }
        fileInfoMapper.updateById(fileInfo);
        assert uploadFile != null;
        BeanUtils.copyProperties(fileInfo, uploadFile);
        
        // 设置预览URL
        String url = minioFileService.preview(uploadFile.getBucketName(), uploadFile.getUrl());
        if (StringUtils.isNotBlank(url) && url.startsWith(minioProperties.getOldUrl())) {
            url = minioProperties.getNewUrl() + url.substring(minioProperties.getOldUrl().length());
        }
        uploadFile.setPreUrl(url);
        
        // 设置缩略图预览URL（如果存在）
        if (StringUtils.isNotBlank(uploadFile.getThumbnailUrl())) {
            try {
                String thumbnailPreUrl = minioFileService.preview(uploadFile.getBucketName(), uploadFile.getThumbnailUrl());
                if (StringUtils.isNotBlank(thumbnailPreUrl) && thumbnailPreUrl.startsWith(minioProperties.getOldUrl())) {
                    thumbnailPreUrl = minioProperties.getNewUrl() + thumbnailPreUrl.substring(minioProperties.getOldUrl().length());
                }
                uploadFile.setThumbnailPreUrl(thumbnailPreUrl);
            } catch (Exception e) {
                log.error("生成缩略图预览URL失败: {}", e.getMessage(), e);
            }
        }
        
        return uploadFile;
    }

    @Override
    public Boolean deleteFileInfo(String ids) {
        if (StringUtils.isEmpty(ids)) {
            return true;
        }
        List<String> idArr = Arrays.asList(ids.split(","));
        fileInfoMapper.deleteBatchIds(idArr);
        return true;
    }

    @Override
    public InputStream fileDownload(Long id) {
        FileInfoVo fileInfo = fileInfoMapper.queryFileInfo(id);
        return minioFileService.fileDownload(fileInfo);
    }

    private FileInfoVo uploadFile(String type, MultipartFile file) throws Exception {
        return minioFileService.uploadFile(file, type);
    }

    @Override
    public List<FileInfoVo> getFileInfo(List<Long> fileIdList) {
        if (fileIdList == null || fileIdList.isEmpty()) {
            return Lists.newArrayList();
        }
        LambdaQueryWrapper<FileInfo> query = Wrappers.<FileInfo>lambdaQuery().in(FileInfo::getId, fileIdList);
        List<FileInfo> fileInfos = fileInfoMapper.selectList(query);
        if (fileInfos == null || fileInfos.isEmpty()) {
            return null;
        }
        
        // 批量获取预览URL
        Map<Long, String> preUrlMap = new HashMap<>();
        Map<Long, String> thumbnailPreUrlMap = new HashMap<>();
        
        fileInfos.forEach(item -> {
            try {
                // 原文件预览URL
                String url = minioFileService.preview(item.getBucketName(), item.getUrl());
                if (StringUtils.isNotBlank(url) && url.startsWith(minioProperties.getOldUrl())) {
                    url = minioProperties.getNewUrl() + url.substring(minioProperties.getOldUrl().length());
                }
                preUrlMap.put(item.getId(), Optional.ofNullable(url).orElse(""));
                
                // 缩略图预览URL（如果存在）
                if (StringUtils.isNotBlank(item.getThumbnailUrl())) {
                    String thumbnailPreUrl = minioFileService.preview(item.getBucketName(), item.getThumbnailUrl());
                    if (StringUtils.isNotBlank(thumbnailPreUrl) && thumbnailPreUrl.startsWith(minioProperties.getOldUrl())) {
                        thumbnailPreUrl = minioProperties.getNewUrl() + thumbnailPreUrl.substring(minioProperties.getOldUrl().length());
                    }
                    thumbnailPreUrlMap.put(item.getId(), Optional.ofNullable(thumbnailPreUrl).orElse(""));
                }
                
                log.info("====================preview====================:{}", url);
            } catch (Exception e) {
                log.info("文件预览失败，文件ID：{}, 错误信息：{}", item.getId(), e.getMessage());
            }
        });
        
        return fileInfos.parallelStream().map(item -> {
            FileInfoVo fileInfoVo = new FileInfoVo();
            BeanUtils.copyProperties(item, fileInfoVo);
            fileInfoVo.setPreUrl(preUrlMap.get(item.getId()));
            fileInfoVo.setThumbnailPreUrl(thumbnailPreUrlMap.get(item.getId()));
            return fileInfoVo;
        }).collect(Collectors.toList());
    }
}
